<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="theme-color" content="#0078E7"><meta name="author" content="爱肖彤真是太好了"><meta name="copyright" content="爱肖彤真是太好了"><meta name="generator" content="Hexo 5.1.1"><meta name="theme" content="hexo-theme-yun"><title>Docker高级 | 工藤旧二の博客</title><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@900&amp;display=swap" media="none" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/star-markdown-css@0.1.19/dist/yun/yun-markdown.min.css"><script src="//at.alicdn.com/t/font_1140697_stqaphw3j4.js" async></script><script src="https://cdn.jsdelivr.net/npm/scrollreveal/dist/scrollreveal.min.js" defer></script><script>document.addEventListener("DOMContentLoaded", () => {
  [".post-card",".post-content img"].forEach((target)=> {
    ScrollReveal().reveal(target);
  })
});
</script><link rel="shortcut icon" type="image/svg+xml" href="/task/yun.ico"><link rel="mask-icon" href="/task/yun.ico" color="#0078E7"><link rel="alternate icon" href="/yun.ico"><link rel="preload" href="/task/css/hexo-theme-yun.css" as="style"><link rel="preload" href="/task/js/utils.js" as="script"><link rel="preload" href="/task/js/hexo-theme-yun.js" as="script"><link rel="prefetch" href="/task/js/sidebar.js" as="script"><link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin><link rel="stylesheet" href="/task/css/hexo-theme-yun.css"><link rel="alternate" href="/task/atom.xml" title="工藤旧二の博客" type="application/atom+xml"><script id="yun-config">
    const Yun = window.Yun || {};
    window.CONFIG = {"root":"/task/","title":"工藤旧二の博客","version":"0.9.7","anonymous_image":"https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/avatar/none.jpg","say":{"api":"https://v1.hitokoto.cn","hitokoto":true},"local_search":{"path":"/task/search.xml"},"fireworks":{"colors":["102, 167, 221","62, 131, 225","33, 78, 194"]}};
  </script><script>(function(){
  var bp = document.createElement('script');
  var curProtocol = window.location.protocol.split(':')[0];
  if (curProtocol === 'https') {
    bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
  }
  else {
    bp.src = 'http://push.zhanzhang.baidu.com/push.js';
  }
  var s = document.getElementsByTagName("script")[0];
  s.parentNode.insertBefore(bp, s);
})();</script><meta name="description" content="一、部署应用映射外部目录# 部署redis，把配置文件和数据目录映射出来 # 操作步骤     # 创建需要被映射的目录     -1 mkdir &#x2F;redis&#x2F;conf &#x2F;redis&#x2F;data     -2 vim &#x2F;redis&#x2F;conf&#x2F;redis.conf         # 配置文件         bind 0.0.0.0         daemonize NO         pro">
<meta property="og:type" content="article">
<meta property="og:title" content="Docker高级">
<meta property="og:url" content="http://huang_zhao.gitee.io/task/2019/09/18/%E5%85%B6%E4%BB%96/Docker%E9%AB%98%E7%BA%A7/index.html">
<meta property="og:site_name" content="工藤旧二の博客">
<meta property="og:description" content="一、部署应用映射外部目录# 部署redis，把配置文件和数据目录映射出来 # 操作步骤     # 创建需要被映射的目录     -1 mkdir &#x2F;redis&#x2F;conf &#x2F;redis&#x2F;data     -2 vim &#x2F;redis&#x2F;conf&#x2F;redis.conf         # 配置文件         bind 0.0.0.0         daemonize NO         pro">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2019-09-18T06:10:11.000Z">
<meta property="article:modified_time" content="2020-09-08T10:38:12.000Z">
<meta property="article:author" content="爱肖彤真是太好了">
<meta property="article:tag" content="Docker">
<meta property="article:tag" content="容器化">
<meta name="twitter:card" content="summary"><script src="/task/js/ui/mode.js"></script><link rel="stylesheet" href="/task/css/prism.css" type="text/css"></head><body><script defer src="https://cdn.jsdelivr.net/npm/animejs@latest/anime.min.js"></script><script defer src="/task/js/ui/fireworks.js"></script><canvas class="fireworks"></canvas><div class="container"><a class="sidebar-toggle hty-icon-button" id="menu-btn"><div class="hamburger hamburger--spin" type="button"><span class="hamburger-box"><span class="hamburger-inner"></span></span></div></a><div class="sidebar-toggle sidebar-overlay"></div><aside class="sidebar"><script src="/task/js/sidebar.js"></script><ul class="sidebar-nav"><li class="sidebar-nav-item sidebar-nav-toc hty-icon-button sidebar-nav-active" data-target="post-toc-wrap" title="文章目录"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-list-ordered"></use></svg></li><li class="sidebar-nav-item sidebar-nav-overview hty-icon-button" data-target="site-overview-wrap" title="站点概览"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-passport-line"></use></svg></li></ul><div class="sidebar-panel" id="site-overview-wrap"><div class="site-info fix-top"><a class="site-author-avatar" href="/task/about/" title="爱肖彤真是太好了"><img width="96" loading="lazy" src="/task/Yun.png" alt="爱肖彤真是太好了"></a><div class="site-author-name"><a href="/task/about/">爱肖彤真是太好了</a></div><a class="site-name" href="/task/about/site.html">工藤旧二の博客</a><sub class="site-subtitle"></sub><div class="site-desciption"></div></div><nav class="site-state"><a class="site-state-item hty-icon-button icon-home" href="/task/" title="首页"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-home-4-line"></use></svg></span></a><div class="site-state-item"><a href="/task/archives/" title="归档"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-archive-line"></use></svg></span><span class="site-state-item-count">57</span></a></div><div class="site-state-item"><a href="/task/categories/" title="分类"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-folder-2-line"></use></svg></span><span class="site-state-item-count">2</span></a></div><div class="site-state-item"><a href="/task/tags/" title="标签"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-price-tag-3-line"></use></svg></span><span class="site-state-item-count">50</span></a></div><a class="site-state-item hty-icon-button" target="_blank" rel="noopener" href="https://yun.yunyoujun.cn" title="文档"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-settings-line"></use></svg></span></a></nav><hr style="margin-bottom:0.5rem"><div class="links-of-author"><a class="links-of-author-item hty-icon-button" rel="noopener" title="RSS" target="_blank" style="color:orange"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-rss-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="QQ" target="_blank" style="color:#12B7F5"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-qq-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="GitHub" target="_blank" style="color:#6e5494"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-github-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="微博" target="_blank" style="color:#E6162D"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-weibo-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="豆瓣" target="_blank" style="color:#007722"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-douban-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" href="https://music.163.com/#/user/home?id=552858287" title="网易云音乐" target="_blank" style="color:#C20C0C"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-netease-cloud-music-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="知乎" target="_blank" style="color:#0084FF"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-zhihu-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" href="https://space.bilibili.com/15081363" title="哔哩哔哩" target="_blank" style="color:#FF8EB3"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-bilibili-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="Twitter" target="_blank" style="color:#1da1f2"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-twitter-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="Telegram Channel" target="_blank" style="color:#0088CC"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-telegram-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="E-Mail" target="_blank" style="color:#8E71C1"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-mail-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="Travelling" target="_blank" style="color:var(--hty-text-color)"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-send-plane-2-line"></use></svg></a></div><hr style="margin:0.5rem 1rem"><div class="links"><a class="links-item hty-icon-button" href="/task/links/" title="我的小伙伴们" style="color:dodgerblue"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-genderless-line"></use></svg></a></div><br><a class="links-item hty-icon-button" id="toggle-mode-btn" href="javascript:;" title="Mode" style="color: #f1cb64"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-contrast-2-line"></use></svg></a></div><div class="sidebar-panel sidebar-panel-active" id="post-toc-wrap"><div class="post-toc"><div class="post-toc-content"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%80%E3%80%81%E9%83%A8%E7%BD%B2%E5%BA%94%E7%94%A8%E6%98%A0%E5%B0%84%E5%A4%96%E9%83%A8%E7%9B%AE%E5%BD%95"><span class="toc-text">一、部署应用映射外部目录</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BA%8C%E3%80%81%E8%BF%81%E7%A7%BB%E4%B8%8E%E5%A4%87%E4%BB%BD"><span class="toc-text">二、迁移与备份</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#2-1-%E5%AE%B9%E5%99%A8%E4%BF%9D%E5%AD%98%E4%B8%BA%E9%95%9C%E5%83%8F"><span class="toc-text">2.1 容器保存为镜像</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-2-%E6%8A%8A%E9%95%9C%E5%83%8F%E6%89%93%E5%8C%85%E6%88%90%E5%8E%8B%E7%BC%A9%E5%8C%85"><span class="toc-text">2.2 把镜像打包成压缩包</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-3-%E6%8A%8A%E5%8E%8B%E7%BC%A9%E5%8C%85%E5%9B%9E%E5%A4%8D%E4%B8%BA%E9%95%9C%E5%83%8F"><span class="toc-text">2.3 把压缩包回复为镜像</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%89%E3%80%81dockerfile"><span class="toc-text">三、dockerfile</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9B%9B%E3%80%81%E9%85%8D%E7%BD%AE%E7%A7%81%E6%9C%89%E4%BB%93%E5%BA%93"><span class="toc-text">四、配置私有仓库</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BA%94%E3%80%81docker-compose"><span class="toc-text">五、docker-compose</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%AD%E3%80%81%E5%A4%9A%E4%B8%AA%E5%AE%B9%E5%99%A8%E9%80%9A%E4%BF%A1"><span class="toc-text">六、多个容器通信</span></a></li></ol></div></div></div></aside><main class="sidebar-translate" id="content"><div id="post"><article class="post-block" itemscope itemtype="https://schema.org/Article"><link itemprop="mainEntityOfPage" href="http://huang_zhao.gitee.io/task/task/2019/09/18/%E5%85%B6%E4%BB%96/Docker%E9%AB%98%E7%BA%A7/"><span hidden itemprop="author" itemscope itemtype="https://schema.org/Person"><meta itemprop="name" content="爱肖彤真是太好了"><meta itemprop="description"></span><span hidden itemprop="publisher" itemscope itemtype="https://schema.org/Organization"><meta itemprop="name" content="工藤旧二の博客"></span><header class="post-header"><h1 class="post-title" itemprop="name headline">Docker高级</h1><div class="post-meta"><div class="post-time" style="display:block"><span class="post-meta-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-calendar-line"></use></svg></span> <time title="创建时间：2019-09-18 14:10:11" itemprop="dateCreated datePublished" datetime="2019-09-18T14:10:11+08:00">2019-09-18</time><span class="post-meta-divider">-</span><span class="post-meta-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-calendar-2-line"></use></svg></span> <time title="修改时间：2020-09-08 18:38:12" itemprop="dateModified" datetime="2020-09-08T18:38:12+08:00">2020-09-08</time></div><span class="post-count"><span class="post-symbolcount"><span class="post-meta-item-icon" title="本文字数"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-file-word-line"></use></svg></span> <span title="本文字数">1.5k</span><span class="post-meta-divider">-</span><span class="post-meta-item-icon" title="阅读时长"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-timer-line"></use></svg></span> <span title="阅读时长">7m</span></span></span><span class="post-busuanzi"><span class="post-meta-divider">-</span><span class="post-meta-item-icon" title="阅读次数"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-eye-line"></use></svg> <span id="busuanzi_value_page_pv"></span></span></span><div class="post-classify"><span class="post-category"><span class="post-meta-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-folder-line"></use></svg></span> <span itemprop="about" itemscope itemtype="https://schema.org/Thing"><a class="category" href="/task/categories/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/" style="--text-color:var(--hty-text-color)" itemprop="url" rel="index"><span itemprop="text">技术分享</span></a></span></span><span class="post-tag"><span class="post-meta-divider">-</span><a class="tag" href="/task/tags/Docker/" style="--text-color:var(--hty-text-color)"><span class="post-meta-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-price-tag-3-line"></use></svg></span><span class="tag-name">Docker</span></a><a class="tag" href="/task/tags/%E5%AE%B9%E5%99%A8%E5%8C%96/" style="--text-color:var(--hty-text-color)"><span class="post-meta-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-price-tag-3-line"></use></svg></span><span class="tag-name">容器化</span></a></span></div></div></header><section class="post-body" itemprop="articleBody"><div class="post-content markdown-body" style="--smc-primary:#0078E7;"><h2 id="一、部署应用映射外部目录"><a href="#一、部署应用映射外部目录" class="headerlink" title="一、部署应用映射外部目录"></a>一、部署应用映射外部目录</h2><pre class=" language-python"><code class="language-python"><span class="token comment" spellcheck="true"># 部署redis，把配置文件和数据目录映射出来</span>
<span class="token comment" spellcheck="true"># 操作步骤</span>
    <span class="token comment" spellcheck="true"># 创建需要被映射的目录</span>
    <span class="token operator">-</span><span class="token number">1</span> mkdir <span class="token operator">/</span>redis<span class="token operator">/</span>conf <span class="token operator">/</span>redis<span class="token operator">/</span>data
    <span class="token operator">-</span><span class="token number">2</span> vim <span class="token operator">/</span>redis<span class="token operator">/</span>conf<span class="token operator">/</span>redis<span class="token punctuation">.</span>conf
        <span class="token comment" spellcheck="true"># 配置文件</span>
        bind <span class="token number">0.0</span><span class="token punctuation">.</span><span class="token number">0.0</span>
        daemonize NO
        protected<span class="token operator">-</span>mode no
        requirepass <span class="token number">123456</span>
      <span class="token operator">-</span><span class="token number">3</span> 创建并运行容器
    docker run <span class="token operator">-</span>p <span class="token number">6378</span><span class="token punctuation">:</span><span class="token number">6379</span> <span class="token operator">-</span><span class="token operator">-</span>name redis_6379 <span class="token operator">-</span>v <span class="token operator">/</span>home<span class="token operator">/</span>hzdir<span class="token operator">/</span>redis<span class="token operator">/</span>conf<span class="token operator">/</span>redis<span class="token punctuation">.</span>conf<span class="token punctuation">:</span><span class="token operator">/</span>etc<span class="token operator">/</span>redis<span class="token operator">/</span>redis<span class="token punctuation">.</span>conf <span class="token operator">-</span>v <span class="token operator">/</span>home<span class="token operator">/</span>hzdir<span class="token operator">/</span>redis<span class="token operator">/</span>data<span class="token punctuation">:</span><span class="token operator">/</span>data <span class="token operator">-</span>di redis redis<span class="token operator">-</span>server <span class="token operator">/</span>etc<span class="token operator">/</span>redis<span class="token operator">/</span>redis<span class="token punctuation">.</span>conf
    <span class="token operator">-</span><span class="token number">4</span> 本地window机器上远程连接到了docker里的redis
    <span class="token operator">-</span><span class="token number">5</span> cmd窗口下
        redis<span class="token operator">-</span>cli <span class="token operator">-</span>h <span class="token number">101.133</span><span class="token punctuation">.</span><span class="token number">225.166</span> <span class="token operator">-</span>p <span class="token number">6378</span>
    <span class="token operator">-</span><span class="token number">6</span> 认证
        auth <span class="token number">123456</span>
    <span class="token operator">-</span><span class="token number">7</span> 写入数据
        set name lqz
    <span class="token operator">-</span><span class="token number">8</span> 保存数据
        save或者是bgsave
    <span class="token operator">-</span><span class="token number">9</span> 在宿主机的<span class="token operator">/</span>redis<span class="token operator">/</span>data路径下就能看到一个文件
    <span class="token operator">-</span><span class="token number">10</span> 不管多少次重启redis容器，数据都还在
    <span class="token operator">-</span><span class="token number">11</span> 原来的redis容器没了，按照第三步再启动一遍，数据都还在</code></pre>
<h2 id="二、迁移与备份"><a href="#二、迁移与备份" class="headerlink" title="二、迁移与备份"></a>二、迁移与备份</h2><h3 id="2-1-容器保存为镜像"><a href="#2-1-容器保存为镜像" class="headerlink" title="2.1 容器保存为镜像"></a>2.1 容器保存为镜像</h3><pre class=" language-python"><code class="language-python">docker commit 容器名字 镜像名字
docker commit <span class="token number">19b</span> mydjango
pip install django<span class="token operator">==</span><span class="token number">1.11</span><span class="token punctuation">.</span><span class="token number">11</span> <span class="token operator">-</span>i https<span class="token punctuation">:</span><span class="token operator">//</span>pypi<span class="token punctuation">.</span>douban<span class="token punctuation">.</span>com<span class="token operator">/</span>simple<span class="token operator">/</span></code></pre>
<h3 id="2-2-把镜像打包成压缩包"><a href="#2-2-把镜像打包成压缩包" class="headerlink" title="2.2 把镜像打包成压缩包"></a>2.2 把镜像打包成压缩包</h3><pre class=" language-python"><code class="language-python">docker save <span class="token operator">-</span>o mydjango<span class="token punctuation">.</span>tar mydjango</code></pre>
<h3 id="2-3-把压缩包回复为镜像"><a href="#2-3-把压缩包回复为镜像" class="headerlink" title="2.3 把压缩包回复为镜像"></a>2.3 把压缩包回复为镜像</h3><pre class=" language-python"><code class="language-python">docker load <span class="token operator">-</span>i mydjango<span class="token punctuation">.</span>tar</code></pre>
<h2 id="三、dockerfile"><a href="#三、dockerfile" class="headerlink" title="三、dockerfile"></a>三、dockerfile</h2><p>通过dockerfile启动多个容器运行django项目通过nginx进行负载均衡</p>
<p>顺序：</p>
<ol>
<li>写一个django项目，写好导入的依赖文件，写好dockerfile镜像配置</li>
<li>通过dockerfile创建镜像</li>
<li>运行镜像生成容器，目录映射Django项目（此时已经可以访问）</li>
<li>通过nginx转发http请求做负载均衡</li>
</ol>
<pre class=" language-python"><code class="language-python"><span class="token number">1</span> dockerfile是什么
    一个文件，里面一堆指令，通过这个文件可以生成镜像
<span class="token number">2</span> dockerfile指令
    命令                      作用
    FROM image_name<span class="token punctuation">:</span>tag    定义了使用哪个基础镜像启动构建流程
    MAINTAINER user_name    声明镜像的创建者
    ENV key value    设置环境变量 <span class="token punctuation">(</span>可以写多条<span class="token punctuation">)</span>
    RUN command    是Dockerfile的核心部分<span class="token punctuation">(</span>可以写多条<span class="token punctuation">)</span>
    <span class="token comment" spellcheck="true"># add 和 copy后面跟的本机路径都必须是相对路径，而且必须是在dockerfile同级下的</span>
    ADD source_dir<span class="token operator">/</span>file dest_dir<span class="token operator">/</span>file    将宿主机的文件复制到容器内，如果是一个压缩文件，将会在复制后自动解压
    COPY source_dir<span class="token operator">/</span>file dest_dir<span class="token operator">/</span>file    和ADD相似，但是如果有压缩文件并不能解压
    WORKDIR path_dir    设置工作目录

<span class="token number">3</span> 写一个dockerfile（文件名字必须交dockerfile）
vim dockerfile
FROM hzpython
MAINTAINER hz
EXPOSE <span class="token number">8080</span>
ADD <span class="token punctuation">.</span><span class="token operator">/</span>requirement<span class="token punctuation">.</span>txt <span class="token operator">/</span>home<span class="token operator">/</span>
RUN pip install <span class="token operator">-</span>r <span class="token operator">/</span>home<span class="token operator">/</span>requirement<span class="token punctuation">.</span>txt <span class="token operator">-</span>i https<span class="token punctuation">:</span><span class="token operator">//</span>pypi<span class="token punctuation">.</span>douban<span class="token punctuation">.</span>com<span class="token operator">/</span>simple<span class="token operator">/</span> 
RUN pip install uwsgi <span class="token operator">-</span>i https<span class="token punctuation">:</span><span class="token operator">//</span>pypi<span class="token punctuation">.</span>douban<span class="token punctuation">.</span>com<span class="token operator">/</span>simple<span class="token operator">/</span>
VOLUME <span class="token punctuation">[</span><span class="token string">"/home"</span><span class="token punctuation">]</span>
WORKDIR <span class="token operator">/</span>home<span class="token operator">/</span>django_test
CMD <span class="token punctuation">[</span><span class="token string">"uwsgi"</span><span class="token punctuation">,</span> <span class="token string">"--ini"</span><span class="token punctuation">,</span> <span class="token string">"/home/django_test/uwsgi.ini"</span><span class="token punctuation">]</span> 
<span class="token comment" spellcheck="true"># 或者</span>
CMD <span class="token punctuation">[</span><span class="token string">"python"</span><span class="token punctuation">,</span> <span class="token string">"/home/text/manage.py"</span><span class="token punctuation">,</span> <span class="token string">"runserver"</span><span class="token punctuation">,</span><span class="token string">"0.0.0.0:8080"</span><span class="token punctuation">]</span> 

<span class="token number">4</span> 通过dockerfile构建出镜像
    docker build <span class="token operator">-</span>t<span class="token operator">=</span><span class="token string">'django_1.11.11'</span> <span class="token punctuation">.</span>
<span class="token number">5</span> 查看镜像
    docker images 
<span class="token number">6</span> 启动容器
docker run <span class="token operator">-</span>di <span class="token operator">-</span><span class="token operator">-</span>name<span class="token operator">=</span>mydjango2 <span class="token operator">-</span>v <span class="token operator">/</span>opt<span class="token operator">/</span>lqz<span class="token operator">/</span><span class="token punctuation">:</span><span class="token operator">/</span>home <span class="token operator">-</span>p <span class="token number">8080</span><span class="token punctuation">:</span><span class="token number">8080</span> django_1<span class="token number">.11</span><span class="token punctuation">.</span><span class="token number">11</span>

<span class="token number">7</span> 在外部访问即可

<span class="token number">8</span> 配置nginx转发
<span class="token comment" spellcheck="true"># 创建文件件</span>
mkdir <span class="token operator">-</span>p <span class="token operator">/</span>opt<span class="token operator">/</span>nginx<span class="token operator">/</span>conf <span class="token operator">/</span>opt<span class="token operator">/</span>nginx<span class="token operator">/</span>html <span class="token operator">/</span>opt<span class="token operator">/</span>nginx<span class="token operator">/</span>logs
<span class="token comment" spellcheck="true"># 新建配置文件</span>
vim nginx<span class="token operator">/</span>conf<span class="token operator">/</span>nginx<span class="token punctuation">.</span>conf
<span class="token comment" spellcheck="true"># 写入</span>
worker_processes  <span class="token number">1</span><span class="token punctuation">;</span>
events <span class="token punctuation">{</span>
    worker_connections  <span class="token number">1024</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
http <span class="token punctuation">{</span>
    include       mime<span class="token punctuation">.</span>types<span class="token punctuation">;</span>
    default_type  application<span class="token operator">/</span>octet<span class="token operator">-</span>stream<span class="token punctuation">;</span>
    sendfile        on<span class="token punctuation">;</span>
    keepalive_timeout  <span class="token number">65</span><span class="token punctuation">;</span>
    upstream node    <span class="token punctuation">{</span>
        server    <span class="token number">101.133</span><span class="token punctuation">.</span><span class="token number">225.166</span><span class="token punctuation">:</span><span class="token number">8080</span><span class="token punctuation">;</span>
        server    <span class="token number">101.133</span><span class="token punctuation">.</span><span class="token number">225.166</span><span class="token punctuation">:</span><span class="token number">8081</span><span class="token punctuation">;</span>
        server    <span class="token number">101.133</span><span class="token punctuation">.</span><span class="token number">225.166</span><span class="token punctuation">:</span><span class="token number">8082</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    server <span class="token punctuation">{</span>
        listen       <span class="token number">80</span><span class="token punctuation">;</span>
        server_name  localhost<span class="token punctuation">;</span>
        location <span class="token operator">/</span> <span class="token punctuation">{</span>
          <span class="token comment" spellcheck="true">#proxy_pass http://101.133.225.166:8080;</span>
          <span class="token comment" spellcheck="true">#负载均衡配置</span>
          proxy_pass http<span class="token punctuation">:</span><span class="token operator">//</span>node<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>  
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token comment" spellcheck="true"># docker 中运行nginx</span>
docker run <span class="token operator">-</span><span class="token operator">-</span>name nginx <span class="token operator">-</span>id <span class="token operator">-</span>p <span class="token number">8888</span><span class="token punctuation">:</span><span class="token number">80</span> <span class="token operator">-</span>v <span class="token operator">/</span>opt<span class="token operator">/</span>nginx<span class="token operator">/</span>conf<span class="token operator">/</span>nginx<span class="token punctuation">.</span>conf<span class="token punctuation">:</span><span class="token operator">/</span>etc<span class="token operator">/</span>nginx<span class="token operator">/</span>nginx<span class="token punctuation">.</span>conf <span class="token operator">-</span>v <span class="token operator">/</span>opt<span class="token operator">/</span>nginx<span class="token operator">/</span>html<span class="token punctuation">:</span><span class="token operator">/</span>etc<span class="token operator">/</span>nginx<span class="token operator">/</span>html <span class="token operator">-</span>v <span class="token operator">/</span>opt<span class="token operator">/</span>nginx<span class="token operator">/</span>logs<span class="token punctuation">:</span><span class="token operator">/</span>var<span class="token operator">/</span>log<span class="token operator">/</span>nginx nginx

<span class="token number">9</span> 配置负载均衡
<span class="token comment" spellcheck="true"># 修改nginx配置文件</span>
worker_processes  <span class="token number">1</span><span class="token punctuation">;</span>
events <span class="token punctuation">{</span>
    worker_connections  <span class="token number">1024</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
http <span class="token punctuation">{</span>
    include       mime<span class="token punctuation">.</span>types<span class="token punctuation">;</span>
    default_type  application<span class="token operator">/</span>octet<span class="token operator">-</span>stream<span class="token punctuation">;</span>
    sendfile        on<span class="token punctuation">;</span>
    keepalive_timeout  <span class="token number">65</span><span class="token punctuation">;</span>
    upstream node    <span class="token punctuation">{</span>
        server    <span class="token number">101.133</span><span class="token punctuation">.</span><span class="token number">225.166</span><span class="token punctuation">:</span><span class="token number">8080</span><span class="token punctuation">;</span>
        server    <span class="token number">101.133</span><span class="token punctuation">.</span><span class="token number">225.166</span><span class="token punctuation">:</span><span class="token number">8081</span><span class="token punctuation">;</span>
        server    <span class="token number">101.133</span><span class="token punctuation">.</span><span class="token number">225.166</span><span class="token punctuation">:</span><span class="token number">8082</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    server <span class="token punctuation">{</span>
        listen       <span class="token number">80</span><span class="token punctuation">;</span>
        server_name  localhost<span class="token punctuation">;</span>
        location <span class="token operator">/</span> <span class="token punctuation">{</span>
          <span class="token comment" spellcheck="true">#proxy_pass http://101.133.225.166:8080;</span>
          <span class="token comment" spellcheck="true">#负载均衡配置</span>
          proxy_pass http<span class="token punctuation">:</span><span class="token operator">//</span>node<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>  
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment" spellcheck="true"># 多启动几个docker容器</span>
docker run <span class="token operator">-</span>di <span class="token operator">-</span><span class="token operator">-</span>name<span class="token operator">=</span>mydjango3 <span class="token operator">-</span>v <span class="token operator">/</span>opt<span class="token operator">/</span>lqz<span class="token operator">/</span>django_test2<span class="token operator">/</span><span class="token punctuation">:</span><span class="token operator">/</span>home<span class="token operator">/</span>django_test<span class="token operator">/</span> <span class="token operator">-</span>p <span class="token number">8081</span><span class="token punctuation">:</span><span class="token number">8080</span> django_1<span class="token number">.11</span><span class="token punctuation">.</span><span class="token number">11</span>
docker run <span class="token operator">-</span>di <span class="token operator">-</span><span class="token operator">-</span>name<span class="token operator">=</span>mydjango3 <span class="token operator">-</span>v <span class="token operator">/</span>opt<span class="token operator">/</span>lqz<span class="token operator">/</span>django_test2<span class="token operator">/</span><span class="token punctuation">:</span><span class="token operator">/</span>home<span class="token operator">/</span>django_test<span class="token operator">/</span> <span class="token operator">-</span>p <span class="token number">8082</span><span class="token punctuation">:</span><span class="token number">8080</span> django_1<span class="token number">.11</span><span class="token punctuation">.</span><span class="token number">11</span>

<span class="token comment" spellcheck="true"># 重启nginx</span>
<span class="token comment" spellcheck="true"># 假设8081的容器挂了，8080的容器挂了，正常提供服务，</span>
<span class="token comment" spellcheck="true"># 再把docker容器启动起来即可</span></code></pre>
<h2 id="四、配置私有仓库"><a href="#四、配置私有仓库" class="headerlink" title="四、配置私有仓库"></a>四、配置私有仓库</h2><pre class=" language-python"><code class="language-python"><span class="token number">1</span> 拉取私有仓库镜像
    docker pull registry
<span class="token number">2</span> 启动容器
    docker run <span class="token operator">-</span>di <span class="token operator">-</span><span class="token operator">-</span>name<span class="token operator">=</span>registry <span class="token operator">-</span>p <span class="token number">5000</span><span class="token punctuation">:</span><span class="token number">5000</span> registry
<span class="token number">3</span> 打开浏览器 输入地址http<span class="token punctuation">:</span><span class="token operator">//</span><span class="token number">101.133</span><span class="token punctuation">.</span><span class="token number">225.166</span><span class="token punctuation">:</span><span class="token number">5000</span><span class="token operator">/</span>v2<span class="token operator">/</span>_catalog看到<span class="token punctuation">{</span><span class="token string">"repositories"</span><span class="token punctuation">:</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">}</span> 表示私有仓库搭建成功并且内容为空
<span class="token number">4</span> 配置
    修改daemon<span class="token punctuation">.</span>json
    vi <span class="token operator">/</span>etc<span class="token operator">/</span>docker<span class="token operator">/</span>daemon<span class="token punctuation">.</span>json
    添加以下内容，保存退出。
    <span class="token punctuation">{</span><span class="token string">"insecure-registries"</span><span class="token punctuation">:</span><span class="token punctuation">[</span><span class="token string">"101.133.225.166:5000"</span><span class="token punctuation">]</span><span class="token punctuation">}</span> 
    此步用于让 docker信任私有仓库地址
<span class="token number">5</span> 重启docker 服务
    systemctl restart docker
<span class="token number">6</span> 重启容器
    docker start registry
<span class="token number">7</span> 打标签
    docker tag <span class="token number">5452fa6715c0</span> <span class="token number">101.133</span><span class="token punctuation">.</span><span class="token number">225.166</span><span class="token punctuation">:</span><span class="token number">5000</span><span class="token operator">/</span>django1<span class="token number">.11</span><span class="token punctuation">.</span><span class="token number">11</span>
<span class="token number">8</span> 上传到私有仓库
docker push <span class="token number">101.133</span><span class="token punctuation">.</span><span class="token number">225.166</span><span class="token punctuation">:</span><span class="token number">5000</span><span class="token operator">/</span>django1<span class="token number">.11</span><span class="token punctuation">.</span><span class="token number">11</span>

<span class="token number">9</span> 从私有仓库拉取镜像
docker pull <span class="token number">101.133</span><span class="token punctuation">.</span><span class="token number">225.166</span><span class="token punctuation">:</span><span class="token number">5000</span><span class="token operator">/</span>django1<span class="token number">.11</span><span class="token punctuation">.</span><span class="token number">11</span></code></pre>
<h2 id="五、docker-compose"><a href="#五、docker-compose" class="headerlink" title="五、docker-compose"></a>五、docker-compose</h2><pre class=" language-python"><code class="language-python"><span class="token number">1</span> docker<span class="token operator">-</span>compose是一个单机情况下容器编排的工具
<span class="token number">2</span> 通过yml文件定义多个容器
<span class="token number">3</span> 默认名字docker<span class="token operator">-</span>compose<span class="token punctuation">.</span>yml
<span class="token number">4</span> 三个概念，Service  Networks ，Volumes
    一个service代表一个container，这个container可以从docker hub的image来创建，或者从本地dockerfile build的image来创建
<span class="token number">5</span> version：有<span class="token number">1</span>，<span class="token number">2</span>，<span class="token number">3</span>版本，目前都用<span class="token string">"3"</span>


<span class="token number">6</span> 安装
curl <span class="token operator">-</span>L https<span class="token punctuation">:</span><span class="token operator">//</span>get<span class="token punctuation">.</span>daocloud<span class="token punctuation">.</span>io<span class="token operator">/</span>docker<span class="token operator">/</span>compose<span class="token operator">/</span>releases<span class="token operator">/</span>download<span class="token operator">/</span><span class="token number">1.25</span><span class="token punctuation">.</span><span class="token number">4</span><span class="token operator">/</span>docker<span class="token operator">-</span>compose<span class="token operator">-</span>`uname <span class="token operator">-</span>s`<span class="token operator">-</span>`uname <span class="token operator">-</span>m` <span class="token operator">></span> <span class="token operator">/</span>usr<span class="token operator">/</span>local<span class="token operator">/</span>bin<span class="token operator">/</span>docker<span class="token operator">-</span>compose
chmod <span class="token operator">+</span>x <span class="token operator">/</span>usr<span class="token operator">/</span>local<span class="token operator">/</span>bin<span class="token operator">/</span>docker<span class="token operator">-</span>compose

<span class="token number">7</span> 验证安装成功
    docker<span class="token operator">-</span>compose <span class="token operator">-</span>v
</code></pre>
<p><strong>应用部署</strong></p>
<pre class=" language-python"><code class="language-python"><span class="token comment" spellcheck="true"># 部署flask redis</span>
<span class="token number">1</span> 创建Dockerfile
vim Dockerfile
FROM python<span class="token punctuation">:</span><span class="token number">3.6</span>
COPY <span class="token punctuation">.</span> <span class="token operator">/</span>app
WORKDIR <span class="token operator">/</span>app
RUN pip install flask redis
EXPOSE <span class="token number">5000</span>
CMD <span class="token punctuation">[</span> <span class="token string">"python"</span><span class="token punctuation">,</span> <span class="token string">"app.py"</span> <span class="token punctuation">]</span>

<span class="token number">2</span> 创建docker<span class="token operator">-</span>compose文件
vim docker<span class="token operator">-</span>compose<span class="token punctuation">.</span>yml
version<span class="token punctuation">:</span> <span class="token string">"3"</span>
services<span class="token punctuation">:</span>
  redis<span class="token punctuation">:</span>
    image<span class="token punctuation">:</span> redis
  web<span class="token punctuation">:</span>
    build<span class="token punctuation">:</span>
      context<span class="token punctuation">:</span> <span class="token punctuation">.</span>
      dockerfile<span class="token punctuation">:</span> Dockerfile
    ports<span class="token punctuation">:</span>
      <span class="token operator">-</span> <span class="token number">8080</span><span class="token punctuation">:</span><span class="token number">5000</span>
    environment<span class="token punctuation">:</span>
      REDIS_HOST<span class="token punctuation">:</span> redis
<span class="token number">3</span> 创建app<span class="token punctuation">.</span>py
vim app<span class="token punctuation">.</span>py
<span class="token keyword">from</span> flask <span class="token keyword">import</span> Flask
<span class="token keyword">from</span> redis <span class="token keyword">import</span> Redis
<span class="token keyword">import</span> os
<span class="token keyword">import</span> socket
app <span class="token operator">=</span> Flask<span class="token punctuation">(</span>__name__<span class="token punctuation">)</span>
redis <span class="token operator">=</span> Redis<span class="token punctuation">(</span>host<span class="token operator">=</span>os<span class="token punctuation">.</span>environ<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">'REDIS_HOST'</span><span class="token punctuation">,</span> <span class="token string">'127.0.0.1'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> port<span class="token operator">=</span><span class="token number">6379</span><span class="token punctuation">)</span>
@app<span class="token punctuation">.</span>route<span class="token punctuation">(</span><span class="token string">'/'</span><span class="token punctuation">)</span>
<span class="token keyword">def</span> <span class="token function">hello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    redis<span class="token punctuation">.</span>incr<span class="token punctuation">(</span><span class="token string">'hits'</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> <span class="token string">'你好! 查看 %s 次， hostname 是 %s.\n'</span> <span class="token operator">%</span> <span class="token punctuation">(</span>redis<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">'hits'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>socket<span class="token punctuation">.</span>gethostname<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">"__main__"</span><span class="token punctuation">:</span>
    app<span class="token punctuation">.</span>run<span class="token punctuation">(</span>host<span class="token operator">=</span><span class="token string">"0.0.0.0"</span><span class="token punctuation">,</span> port<span class="token operator">=</span><span class="token number">5000</span><span class="token punctuation">,</span> debug<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">)</span>
<span class="token number">4</span> 启动<span class="token operator">-</span><span class="token operator">-</span>运行
docker<span class="token operator">-</span>compose up</code></pre>
<h2 id="六、多个容器通信"><a href="#六、多个容器通信" class="headerlink" title="六、多个容器通信"></a>六、多个容器通信</h2><pre class=" language-python"><code class="language-python"><span class="token number">1</span> 端口映射到宿主机，直接访问宿主机
<span class="token number">2</span> 通过ip地址访问
<span class="token number">3</span> run的时候指定 <span class="token operator">-</span><span class="token operator">-</span>link 容器 
docker run <span class="token operator">-</span>di <span class="token operator">-</span><span class="token operator">-</span>name<span class="token operator">=</span>centos1 centos<span class="token punctuation">:</span>centos7
docker run <span class="token operator">-</span>di <span class="token operator">-</span><span class="token operator">-</span>name<span class="token operator">=</span>centos2 <span class="token operator">-</span><span class="token operator">-</span>link centos1 centos<span class="token punctuation">:</span>centos7

进入到centos2中 ping centos1 可以ping同


<span class="token comment" spellcheck="true"># 跨主机的容器通信</span>
    <span class="token operator">-</span>端口映射</code></pre>
</div><div id="reward-container"><span class="hty-icon-button button-glow" id="reward-button" title="打赏" onclick="var qr = document.getElementById(&quot;qr&quot;); qr.style.display = (qr.style.display === &quot;none&quot;) ? &quot;block&quot; : &quot;none&quot;;"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-hand-coin-line"></use></svg></span><div id="reward-comment">点我就给你看点有意思的</div><div id="qr" style="display:none;"><div style="display:inline-block"><a target="_blank" rel="noopener" href="https://gitee.com/huang_zhao/hz/raw/master/hz/alipay.png"><img loading="lazy" src="https://gitee.com/huang_zhao/hz/raw/master/hz/alipay.png" alt="支付宝" title="支付宝"></a><div><span style="color:#00A3EE"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-alipay-line"></use></svg></span></div></div><div style="display:inline-block"><a target="_blank" rel="noopener" href="https://gitee.com/huang_zhao/hz/raw/master/hz/qqpay.jpg"><img loading="lazy" src="https://gitee.com/huang_zhao/hz/raw/master/hz/qqpay.jpg" alt="QQ 支付" title="QQ 支付"></a><div><span style="color:#12B7F5"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-qq-line"></use></svg></span></div></div><div style="display:inline-block"><a target="_blank" rel="noopener" href="https://gitee.com/huang_zhao/hz/raw/master/hz/wxpay.jpg"><img loading="lazy" src="https://gitee.com/huang_zhao/hz/raw/master/hz/wxpay.jpg" alt="微信支付" title="微信支付"></a><div><span style="color:#2DC100"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-wechat-pay-line"></use></svg></span></div></div></div></div><ul class="post-copyright"><li class="post-copyright-author"><strong>本文作者：</strong>爱肖彤真是太好了</li><li class="post-copyright-link"><strong>本文链接：</strong><a href="http://huang_zhao.gitee.io/task/2019/09/18/%E5%85%B6%E4%BB%96/Docker%E9%AB%98%E7%BA%A7/" title="Docker高级">http://huang_zhao.gitee.io/task/2019/09/18/%E5%85%B6%E4%BB%96/Docker%E9%AB%98%E7%BA%A7/</a></li><li class="post-copyright-license"><strong>版权声明：</strong>本博客所有文章除特别声明外，均默认采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh" target="_blank" rel="noopener" title="CC BY-NC-SA 4.0 "><svg class="icon"><use xlink:href="#icon-creative-commons-line"></use></svg><svg class="icon"><use xlink:href="#icon-creative-commons-by-line"></use></svg><svg class="icon"><use xlink:href="#icon-creative-commons-nc-line"></use></svg><svg class="icon"><use xlink:href="#icon-creative-commons-sa-line"></use></svg></a> 许可协议。</li></ul></section></article><div class="post-nav"><div class="post-nav-item"><a class="post-nav-prev" href="/task/2020/01/09/go/%E5%9F%BA%E7%A1%80/GO%E5%85%A5%E9%97%A8/" rel="prev" title="Go语言基础"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-arrow-left-s-line"></use></svg><span class="post-nav-text">Go语言基础</span></a></div><div class="post-nav-item"><a class="post-nav-next" href="/task/2019/08/15/%E5%85%B6%E4%BB%96/Docker%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C/" rel="next" title="Docker常用操作"><span class="post-nav-text">Docker常用操作</span><svg class="icon" aria-hidden="true"><use xlink:href="#icon-arrow-right-s-line"></use></svg></a></div></div></div></main><footer class="sidebar-translate" id="footer"><div class="copyright"><span>&copy; 2019 – 2022 </span><span class="with-love" id="animate"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-cloud-line"></use></svg></span><span class="author"> 爱肖彤真是太好了</span></div><div class="powered"><span>由 <a href="https://hexo.io" target="_blank" rel="noopener">Hexo</a> 驱动 v5.1.1</span><span class="footer-separator">|</span><span>主题 - <a rel="noopener" href="https://github.com/YunYouJun/hexo-theme-yun" target="_blank"><span>Yun</span></a> v0.9.7</span></div><div class="live_time"><span>本博客已萌萌哒地运行</span><span id="display_live_time"></span><span class="moe-text">(●'◡'●)</span><script>function blog_live_time() {
  window.setTimeout(blog_live_time, 1000);
  const start = new Date('2019-04-12T00:00:00');
  const now = new Date();
  const timeDiff = (now.getTime() - start.getTime());
  const msPerMinute = 60 * 1000;
  const msPerHour = 60 * msPerMinute;
  const msPerDay = 24 * msPerHour;
  const passDay = Math.floor(timeDiff / msPerDay);
  const passHour = Math.floor((timeDiff % msPerDay) / 60 / 60 / 1000);
  const passMinute = Math.floor((timeDiff % msPerHour) / 60 / 1000);
  const passSecond = Math.floor((timeDiff % msPerMinute) / 1000);
  display_live_time.innerHTML = " " + passDay + " 天 " + passHour + " 小时 " + passMinute + " 分 " + passSecond + " 秒";
}
blog_live_time();
</script></div><div id="busuanzi"><script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script><span id="busuanzi_container_site_uv" title="总访客量"><span><svg class="icon" aria-hidden="true"><use xlink:href="#icon-user-line"></use></svg></span><span id="busuanzi_value_site_uv"></span></span><span class="footer-separator">|</span><span id="busuanzi_container_site_pv" title="总访问量"><span><svg class="icon" aria-hidden="true"><use xlink:href="#icon-eye-line"></use></svg></span><span id="busuanzi_value_site_pv"></span></span></div></footer><a class="hty-icon-button" id="goUp" aria-label="back-to-top" href="#"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-arrow-up-s-line"></use></svg><svg class="progress-circle-container" viewBox="0 0 100 100"><circle class="progress-circle" id="progressCircle" cx="50" cy="50" r="48" fill="none" stroke="#0078E7" stroke-width="2" stroke-linecap="round"></circle></svg></a><a class="popup-trigger hty-icon-button icon-search" id="search" href="javascript:;" title="搜索"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-search-line"></use></svg></span></a><script>window.addEventListener("DOMContentLoaded", () => {
  // Handle and trigger popup window
  document.querySelector(".popup-trigger").addEventListener("click", () => {
    document.querySelector(".popup").classList.add("show");
    setTimeout(() => {
      document.querySelector(".search-input").focus();
    }, 100);
  });

  // Monitor main search box
  const onPopupClose = () => {
    document.querySelector(".popup").classList.remove("show");
  };

  document.querySelector(".popup-btn-close").addEventListener("click", () => {
    onPopupClose();
  });

  window.addEventListener("keyup", event => {
    if (event.key === "Escape") {
      onPopupClose();
    }
  });
});
</script><script src="/task/js/search/local-search.js" defer></script><div class="popup search-popup"><div class="search-header"><span class="popup-btn-close close-icon hty-icon-button"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-close-line"></use></svg></span></div><div class="search-input-container"><input class="search-input" id="local-search-input" type="text" placeholder="搜索..." value=""></div><div id="local-search-result"></div></div></div><script defer src="/task/js/utils.js"></script><script defer src="/task/js/hexo-theme-yun.js"></script></body></html>